home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Games / DrawSprocketTest / DrawSprocketTest.c next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  42.0 KB  |  1,599 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        DrawSprocketTest.c
  3.     
  4.     Description: Simple implementation of DrawSprcoket functions for testing
  5.  
  6.     Author:        cjd
  7.  
  8.     Copyright:     © Copyright 1999 Apple Computer, Inc. All rights reserved.
  9.     
  10.     Disclaimer:    IMPORTANT:  This Apple software is supplied to you by Apple Computer, Inc.
  11.                 ("Apple") in consideration of your agreement to the following terms, and your
  12.                 use, installation, modification or redistribution of this Apple software
  13.                 constitutes acceptance of these terms.  If you do not agree with these terms,
  14.                 please do not use, install, modify or redistribute this Apple software.
  15.  
  16.                 In consideration of your agreement to abide by the following terms, and subject
  17.                 to these terms, Apple grants you a personal, non-exclusive license, under Apple’s
  18.                 copyrights in this original Apple software (the "Apple Software"), to use,
  19.                 reproduce, modify and redistribute the Apple Software, with or without
  20.                 modifications, in source and/or binary forms; provided that if you redistribute
  21.                 the Apple Software in its entirety and without modifications, you must retain
  22.                 this notice and the following text and disclaimers in all such redistributions of
  23.                 the Apple Software.  Neither the name, trademarks, service marks or logos of
  24.                 Apple Computer, Inc. may be used to endorse or promote products derived from the
  25.                 Apple Software without specific prior written permission from Apple.  Except as
  26.                 expressly stated in this notice, no other rights or licenses, express or implied,
  27.                 are granted by Apple herein, including but not limited to any patent rights that
  28.                 may be infringed by your derivative works or by other works in which the Apple
  29.                 Software may be incorporated.
  30.  
  31.                 The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO
  32.                 WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
  33.                 WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  34.                 PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
  35.                 COMBINATION WITH YOUR PRODUCTS.
  36.  
  37.                 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
  38.                 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  39.                 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  40.                 ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
  41.                 OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
  42.                 (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
  43.                 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  44.                 
  45.     Change History (most recent first):
  46.  
  47.       <SP33>      2/3/99    cjd        Adding DSpGetVersion test
  48.       <SP32>     1/26/99    cjd        Removing code from GSp, overlays, scaling
  49.       <SP31>    10/19/98    cjd        Updating so that it is buildable by MPW
  50.  
  51. */
  52.  
  53. //•    ------------------------------    Includes
  54.  
  55. #include <CodeFragments.h>
  56. #include <Dialogs.h>
  57. #include <Displays.h>
  58. #include <DrawSprocket.h>
  59. #include <Events.h>
  60. #include <Fonts.h>
  61. #include <MacMemory.h>
  62. #include <MacWindows.h>
  63. #include <Menus.h>
  64. #include <Quickdraw.h>
  65. #include <Resources.h>
  66. #include <TextEdit.h>
  67. #include <Timer.h>
  68.  
  69. #if defined (__MWERKS__)
  70. //#include <Math Routines.h>
  71. #endif
  72.  
  73. #include <stdio.h>
  74. #include <string.h>
  75. #include <stdlib.h>
  76. #include <math.h>
  77.  
  78. #if defined (__MWERKS__)
  79. #include <sioux.h>
  80. #else
  81. #include <SIOW.h>
  82. #endif
  83.  
  84. //•    ------------------------------    Private Definitions
  85.  
  86. #define kRectSize            16
  87. #define kDisplayWidth        640
  88. #define kDisplayHeight        480
  89. #define kDisplayDepth        8
  90.  
  91. //•    ------------------------------    Private Types
  92. //•    ------------------------------    Private Variables
  93.  
  94. static Boolean    gVBLSync = true;
  95. static char        gTextBuffer[512];
  96.  
  97. //•    ------------------------------    Private Functions
  98.  
  99. void main(void);
  100. static void ErrorMessage(char *inMessage, OSStatus inError);
  101. static void DumpContextAttributes(DSpContextAttributes *inAttributes);
  102. static void MyInitAttributes(DSpContextAttributes *inAttributes);
  103.  
  104. static void TestDrawSprocket(void);
  105. static void TestContextIteration(void);
  106. static void TestContextSearchingAuto(void);
  107. static void TestContextSearchingManual(void);
  108. static void TestContextBuffering(Boolean inUseUnderlay, Boolean inUseSingleBuffer);
  109. static void TestContextCLUT(void);
  110. static void TestUserSelectContext(void);
  111. static void TestFlatContexts(void);
  112. static void TestGetVersion(void);
  113.  
  114. //•    ------------------------------    Public Variables
  115.  
  116. #pragma mark ##### support routines #####
  117.  
  118. //•    --------------------    main
  119.  
  120. void
  121. main(void)
  122. {
  123. OSStatus    theError;
  124.     
  125. #if defined (__MWERKS__)
  126.     /* tell SIOUX to shut up */
  127.     SIOUXSettings.autocloseonquit = true;
  128.     SIOUXSettings.asktosaveonclose = false;
  129. #endif
  130.     
  131.     /* startup DrawSprocket */
  132.     theError = DSpStartup();
  133.  
  134.     if (theError)
  135.     {
  136.         ErrorMessage("DSpStartup()", theError);
  137.         return;
  138.     }
  139.     
  140.     /* main test menu */
  141.     TestDrawSprocket();
  142.     
  143.     /* shutdown draw sprocket */
  144.     theError = DSpShutdown();
  145.  
  146.     if (theError)
  147.         ErrorMessage("DSpShutdown()", theError);
  148. }
  149.  
  150. //•    --------------------    ErrorMessage
  151.  
  152. void
  153. ErrorMessage(
  154.     char        *inMessage,
  155.     OSStatus    inError
  156. )
  157. {
  158. UInt32    theIndex;
  159.  
  160. static char *theErrorTexts[] =
  161. {
  162.     "Unknown Error",
  163.     "kDSpNotInitializedErr",
  164.     "kDSpSystemSWTooOldErr",
  165.     "kDSpInvalidContextErr",
  166.     "kDSpInvalidAttributesErr",
  167.     "kDSpContextAlreadyReservedErr",
  168.     "kDSpContextNotReservedErr",
  169.     "kDSpContextNotFoundErr",
  170.     "kDSpFrameRateNotReadyErr",
  171.     "kDSpConfirmSwitchWarning",
  172.     "kDSpInternalErr"
  173. };
  174.     
  175.     /* convert the error code into an array index */    
  176.     if (inError <= kDSpNotInitializedErr &&    inError >= kDSpInternalErr)
  177.         theIndex = kDSpNotInitializedErr - inError + 1;
  178.     else
  179.         theIndex = 0;
  180.     
  181.     /* print the message */
  182.     printf("# Error %d (%s) encountered: %s\n", inError, theErrorTexts[theIndex], inMessage);
  183. }
  184.  
  185. //•    --------------------    DumpContextAttributes
  186.  
  187. void
  188. DumpContextAttributes(DSpContextAttributes *inAttributes)
  189. {
  190.     printf("\t             frequency : ");
  191.  
  192.     if (inAttributes->frequency)
  193.         printf("%dhz\n", inAttributes->frequency>>16);
  194.     else
  195.         printf("(unknown)\n");
  196.  
  197.     printf("\t          displayWidth : %d\n", inAttributes->displayWidth);
  198.     printf("\t         displayHeight : %d\n", inAttributes->displayHeight);
  199.     
  200.     printf("\t            colorNeeds : ");
  201.  
  202.     switch (inAttributes->colorNeeds)
  203.     {
  204.         case kDSpColorNeeds_DontCare:
  205.             printf("kDSpColorNeeds_DontCare\n");
  206.             break;
  207.     
  208.         case kDSpColorNeeds_Request:
  209.             printf("kDSpColorNeeds_Request\n");
  210.             break;
  211.     
  212.         case kDSpColorNeeds_Require:
  213.             printf("kDSpColorNeeds_Require\n");
  214.             break;
  215.     
  216.         default:
  217.             printf(" %d (Unknown)\n", inAttributes->colorNeeds);
  218.             break;
  219.     }
  220.     
  221.     printf("\t            colorTable : 0x%X\n", inAttributes->colorTable);
  222.     
  223.     printf("\t        contextOptions : \n");
  224.  
  225.     if (inAttributes->contextOptions & kDSpContextOption_PageFlip)
  226.         printf("\t                         kDSpContextOption_PageFlip\n");
  227.  
  228.     if (0 == inAttributes->contextOptions)
  229.         printf("\t                     (no options set)\n");
  230.         
  231.     printf("\t   backBufferDepthMask : 0x%X\n", inAttributes->backBufferDepthMask);
  232.     printf("\t      displayDepthMask : 0x%X\n", inAttributes->displayDepthMask);
  233.     printf("\t   backBufferBestDepth : %d\n", inAttributes->backBufferBestDepth);
  234.     printf("\t      displayBestDepth : %d\n", inAttributes->displayBestDepth);
  235.     printf("\t             pageCount : %d\n", inAttributes->pageCount);
  236.     
  237.     printf("\t gameMustConfirmSwitch : ");
  238.  
  239.     if (inAttributes->gameMustConfirmSwitch)
  240.         printf("TRUE\n");
  241.     else
  242.         printf("FALSE\n");
  243. }
  244.  
  245. //•    --------------------    MyInitAttributes
  246.  
  247. void
  248. MyInitAttributes(DSpContextAttributes *inAttributes)
  249. {
  250.     if (nil == inAttributes)
  251.         DebugStr("\pStimpy! You Idiot!");
  252.         
  253.     inAttributes->frequency                    = 0;
  254.     inAttributes->displayWidth                = 0;
  255.     inAttributes->displayHeight                = 0;
  256.     inAttributes->reserved1                    = 0;
  257.     inAttributes->reserved2                    = 0;
  258.     inAttributes->colorNeeds                = 0;
  259.     inAttributes->colorTable                = nil;
  260.     inAttributes->contextOptions            = 0;
  261.     inAttributes->backBufferDepthMask        = 0;
  262.     inAttributes->displayDepthMask            = 0;
  263.     inAttributes->backBufferBestDepth        = 0;
  264.     inAttributes->displayBestDepth            = 0;
  265.     inAttributes->pageCount                    = 0;
  266.     inAttributes->gameMustConfirmSwitch        = false;
  267.     inAttributes->reserved3[0]                = 0;
  268.     inAttributes->reserved3[1]                = 0;
  269.     inAttributes->reserved3[2]                = 0;
  270.     inAttributes->reserved3[3]                = 0;
  271. }
  272.  
  273. #pragma mark ##### test routines #####
  274.  
  275. //•    --------------------    TestDrawSprocket
  276.  
  277. void
  278. TestDrawSprocket(void)
  279. {
  280. Boolean    theDoneFlag = false;
  281.     
  282.     while (false == theDoneFlag)
  283.     {
  284.     UInt32    theChoice;
  285.         
  286.         printf("\n\n############################################################\n");
  287.         printf("DrawSprocket test application.\n");
  288.         printf("Please select from the following tests:\n");        
  289.         
  290.         printf("\t 1. Exit\n");
  291.         printf("\t 2. Get Version\n");
  292.         printf("\t 4. Display/context iteration\n");
  293.         printf("\t 5. Context searching (auto selection of w/h/d/d)\n");
  294.         printf("\t 6. Context searching (you specify w/h/d/d)\n");
  295.         printf("\t 7. Multiple-buffering/page flipping (640x480x8)\n");
  296.         printf("\t 8. CLUT operations\n");
  297.         printf("\t 9. DSpUserSelectContext\n");
  298.         printf("\t10. Underlays\n");
  299.         printf("\t14. Single Buffering\n");
  300.  
  301.         if (gVBLSync)
  302.             printf("\t15. Disable VBL Sync\n");
  303.         else
  304.             printf("\t15. Enable VBL Sync\n");
  305.  
  306.         printf("\t16. Test context flattening\n");
  307.         
  308.         printf("\n\tSelection: ");
  309.         gets(gTextBuffer);
  310.         theChoice = atoi(gTextBuffer);
  311.  
  312.         switch (theChoice)
  313.         {
  314.             case 1:        //•    Exit
  315.                 theDoneFlag = true;
  316.                 break;
  317.                 
  318.             case 2:        //•    Get version
  319.                 TestGetVersion();
  320.                 break;
  321.  
  322.             case 4:        //•    Context iteration
  323.                 TestContextIteration();
  324.                 break;            
  325.             
  326.             case 5:        //•    Auto context searching
  327.                 TestContextSearchingAuto();
  328.                 break;
  329.  
  330.             case 6:        //•    Manual context searching
  331.                 TestContextSearchingManual();
  332.                 break;
  333.                 
  334.             case 7:        //•    Buffering
  335.                 TestContextBuffering(false, false);
  336.                 break;
  337.             
  338.             case 8:        //•    CLUT
  339.                 TestContextCLUT();
  340.                 break;
  341.             
  342.             case 9:        //•    User select context
  343.                 TestUserSelectContext();
  344.                 break;
  345.                         
  346.             case 10:    //•    Underlay
  347.                 TestContextBuffering(true, false);
  348.                 break;
  349.             
  350.             case 14:    //•    Single buffer
  351.                 TestContextBuffering(false, true);
  352.                 break;
  353.                 
  354.             case 15:    //•    Toggle sync
  355.                 gVBLSync ^= 1;
  356.                 break;
  357.             
  358.             case 16:    //•    Context flattening
  359.                 TestFlatContexts();
  360.                 break;
  361.  
  362.             default:    //•    Unknown
  363.                 printf("\nhuh?\n");
  364.                 break;            
  365.         }
  366.         
  367.         printf("\nThank you, please drive through.\n");
  368.     }
  369. }
  370.  
  371. //•    --------------------    TestContextInteration
  372.  
  373. void
  374. TestContextIteration(void)
  375. {
  376. GDHandle    theGDevice;
  377. OSStatus    theError;
  378.     
  379.     printf("\n\n");
  380.     printf("############################################################\n");
  381.     printf("###          Testing Display/Context Iteration           ###\n");
  382.     printf("############################################################\n");
  383.     printf("\n\n");
  384.  
  385.     /*
  386.     ** Walk the list of display devices in the system.  DrawSprocket is
  387.     ** centered around the DisplayIDType, which is used by the Display
  388.     ** Manager.  The GDevice records are going to be in flux with future
  389.     ** versions of the system software, so it is best to make the change
  390.     ** now and make your software DisplayManager-centric.
  391.     */
  392.     theGDevice = DMGetFirstScreenDevice(false);
  393.  
  394.     while (theGDevice)
  395.     {
  396.     DisplayIDType        theDisplayID;
  397.     DSpContextReference    theContext;
  398.     UInt32                theContextIndex = 0;
  399.         
  400.         /* get the display ID */
  401.         theError = DMGetDisplayIDByGDevice(theGDevice, &theDisplayID, false);
  402.  
  403.         if (theError)
  404.         {
  405.             ErrorMessage("DMGetDisplayIDByGDevice", theError);
  406.             return;
  407.         }
  408.         
  409.         /* walk the list of contexts for this display */
  410.         theError = DSpGetFirstContext(theDisplayID, &theContext);
  411.  
  412.         while (noErr == theError)
  413.         {
  414.         DSpContextAttributes    theAttributes;
  415.             
  416.             /* obtain the context attributes */
  417.             theError = DSpContext_GetAttributes(theContext, &theAttributes);
  418.  
  419.             if (theError)
  420.             {
  421.                 ErrorMessage("DSpContext_GetAttributes", theError);
  422.                 return;
  423.             }
  424.             
  425.             /* display the attributes structure */
  426.             printf("Display %d, Context %d capabilities:\n", theDisplayID, theContextIndex++);
  427.  
  428.             DumpContextAttributes(&theAttributes);
  429.  
  430.             /*
  431.             ** get the next context.  when a kDSpContextNotFoundErr code
  432.             ** is returned we have hit the end of the context list.  if
  433.             ** a different error code is returned, something went wrong.
  434.             */
  435.             theError = DSpGetNextContext(theContext, &theContext);
  436.  
  437.             if (theError && (kDSpContextNotFoundErr != theError))
  438.             {
  439.                 ErrorMessage("DSpGetNextContext", theError);
  440.                 return;
  441.             }
  442.         }
  443.  
  444.         /* next device */
  445.         theGDevice = DMGetNextScreenDevice(theGDevice, false);
  446.     }    
  447. }
  448.  
  449. //•    --------------------    TestContextSearchingAuto
  450.  
  451. void
  452. TestContextSearchingAuto(void)
  453. {
  454. DSpContextAttributes    theDesiredAttributes;
  455. DSpContextReference        theContext;
  456. OSStatus                theError;
  457.     
  458.     printf("\n\n");
  459.     printf("############################################################\n");
  460.     printf("###          Testing Display/Context Searching           ###\n");
  461.     printf("############################################################\n");
  462.     printf("\n\n");
  463.  
  464.     /*
  465.     ** Find a 640x480x8 mode
  466.     **
  467.     ** First, init the attributes so that there will be no garbage in any
  468.     ** of the fields (and which will cause DS to return an error).  This
  469.     ** is especially important for fields that DS can't check, such as
  470.     ** the colorTable.  If the colorTable is bogus when a call to reserve
  471.     ** a context is made, then it will try to use the bogus color table
  472.     ** (causing unpleasant visits to the debugger).
  473.     **
  474.     ** When using DSpFindBestContext(), the attributes are interpreted as
  475.     ** *REQUIREMENTS*, unlike when you call DSpContext_Reserve(), when
  476.     ** they are interpreted as *REQUESTS*.  If I specify a contextOption
  477.     ** of kDSpContextOption_PageFlip here, only contexts with the ability
  478.     ** to page flip will be considered in the search, however if I specify
  479.     ** the same option when reserving the context, and page flipping is not
  480.     ** available, then DS will use software double/triple buffering.  This
  481.     ** is so to make it easy for the game to always request that DS use
  482.     ** page flipping if it is there (at reservation time), but still continue
  483.     ** if it is not.  Conversely, the game can search for only contexts
  484.     ** that meet a specific criteria, and know that any matches found will
  485.     ** meet those specifications.
  486.     */
  487.     MyInitAttributes(&theDesiredAttributes);
  488.  
  489.     theDesiredAttributes.displayWidth            = 640;
  490.     theDesiredAttributes.displayHeight            = 480;
  491.     theDesiredAttributes.colorNeeds                = kDSpColorNeeds_Require;
  492.     theDesiredAttributes.backBufferDepthMask    = kDSpDepthMask_8;
  493.     theDesiredAttributes.displayDepthMask        = kDSpDepthMask_8;
  494.     theDesiredAttributes.backBufferBestDepth    = kDisplayDepth;
  495.     theDesiredAttributes.displayBestDepth        = kDisplayDepth;
  496.     theDesiredAttributes.pageCount                = 2;
  497.  
  498.     theError = DSpFindBestContext(&theDesiredAttributes, &theContext);
  499.  
  500.     if (theError && kDSpContextNotFoundErr != theError)
  501.     {
  502.         ErrorMessage("DSpFindBestContext 640x480x8", theError);
  503.         return;
  504.     }
  505.  
  506.     if (kDSpContextNotFoundErr == theError)
  507.     {
  508.         printf("# Unable to find a matching context for the following attributes:\n");
  509.         DumpContextAttributes(&theDesiredAttributes);
  510.         return;
  511.     }
  512.     else
  513.     {
  514.     DSpContextAttributes    theActualAttributes;
  515.     DisplayIDType            theDisplayID;
  516.         
  517.         /* get the actual attributes for the context */
  518.         theError = DSpContext_GetAttributes(theContext, &theActualAttributes);
  519.  
  520.         if (theError)
  521.         {
  522.             ErrorMessage("DSpContext_GetAttributes", theError);
  523.             return;
  524.         }
  525.  
  526.         /* get the display id for the context */
  527.         theError = DSpContext_GetDisplayID(theContext, &theDisplayID);
  528.  
  529.         if (theError)
  530.         {
  531.             ErrorMessage("DSpContext_GetDisplayID", theError);
  532.             return;
  533.         }
  534.  
  535.         /* tell the user about the results */
  536.         printf("Best matching Context for the following attributes...\n");
  537.         DumpContextAttributes(&theDesiredAttributes);
  538.  
  539.         printf("...is the context on display id %d with these attributes:\n", theDisplayID);
  540.  
  541.         DumpContextAttributes(&theActualAttributes);
  542.     }
  543. }
  544.  
  545. //•    --------------------    TestContextSearchingManual
  546.  
  547. void
  548. TestContextSearchingManual(void)
  549. {
  550. DSpContextAttributes    theDesiredAttributes;
  551. DSpContextReference        theContext;
  552. OSStatus                theError;
  553.     
  554.     printf("\n\n");
  555.     printf("############################################################\n");
  556.     printf("###          Testing Display/Context Searching           ###\n");
  557.     printf("############################################################\n");
  558.     printf("\n\n");
  559.  
  560.     /* get the context attributes */
  561.     MyInitAttributes(&theDesiredAttributes);
  562.     theDesiredAttributes.pageCount                = 2;
  563.  
  564.     printf("enter the display width: ");
  565.     gets(gTextBuffer);
  566.     theDesiredAttributes.displayWidth            = atoi(gTextBuffer);
  567.  
  568.     if (0 == theDesiredAttributes.displayWidth)
  569.     {
  570.         printf("bogus value!\n");
  571.         return;
  572.     }
  573.     
  574.     printf("enter the display height: ");
  575.     gets(gTextBuffer);
  576.     theDesiredAttributes.displayHeight            = atoi(gTextBuffer);
  577.  
  578.     if (0 == theDesiredAttributes.displayHeight)
  579.     {
  580.         printf("bogus value!\n");
  581.         return;
  582.     }
  583.     
  584.     printf("enter the back buffer best depth: ");
  585.     gets(gTextBuffer);
  586.     theDesiredAttributes.backBufferBestDepth    = atoi(gTextBuffer);
  587.  
  588.     if (0 == theDesiredAttributes.backBufferBestDepth)
  589.     {
  590.         printf("bogus value!\n");
  591.         return;
  592.     }
  593.     
  594.     printf("enter the display best depth: ");
  595.     gets(gTextBuffer);
  596.     theDesiredAttributes.displayBestDepth        = atoi(gTextBuffer);
  597.  
  598.     if (0 == theDesiredAttributes.displayBestDepth)
  599.     {
  600.         printf("bogus value!\n");
  601.         return;
  602.     }
  603.     
  604.     theDesiredAttributes.colorNeeds                = kDSpColorNeeds_Require;
  605.     theDesiredAttributes.backBufferDepthMask    = theDesiredAttributes.backBufferBestDepth;
  606.     theDesiredAttributes.displayDepthMask        = theDesiredAttributes.displayBestDepth;
  607.  
  608.     /* find the context */
  609.     theError = DSpFindBestContext(&theDesiredAttributes, &theContext);
  610.  
  611.     if (theError && kDSpContextNotFoundErr != theError)
  612.     {
  613.         ErrorMessage("DSpFindBestContext (Manual)", theError);
  614.         return;
  615.     }
  616.  
  617.     if (kDSpContextNotFoundErr == theError)
  618.     {
  619.         printf("# Unable to find a matching context for the following attributes:\n");
  620.         DumpContextAttributes(&theDesiredAttributes);
  621.         return;
  622.     }
  623.     else
  624.     {
  625.     DSpContextAttributes    theActualAttributes;
  626.     DisplayIDType            theDisplayID;
  627.         
  628.         /* get the actual attributes for the context */
  629.         theError = DSpContext_GetAttributes(theContext, &theActualAttributes);
  630.  
  631.         if (theError)
  632.         {
  633.             ErrorMessage("DSpContext_GetAttributes", theError);
  634.             return;
  635.         }
  636.  
  637.         /* get the display id for the context */
  638.         theError = DSpContext_GetDisplayID(theContext, &theDisplayID);
  639.  
  640.         if (theError)
  641.         {
  642.             ErrorMessage("DSpContext_GetDisplayID", theError);
  643.             return;
  644.         }
  645.  
  646.         /* tell the user about the results */
  647.         printf("Best matching Context for the following attributes...\n");
  648.         DumpContextAttributes(&theDesiredAttributes);
  649.  
  650.         printf("...is the context on display id %d with these attributes:\n", theDisplayID);
  651.         DumpContextAttributes(&theActualAttributes);
  652.     }
  653. }
  654.  
  655. //•    --------------------    TestContextBuffering
  656.  
  657. void
  658. TestContextBuffering(
  659.     Boolean inUseUnderlay,
  660.     Boolean inUseSingleBuffer
  661. )
  662. {
  663. DSpContextAttributes    theDesiredAttributes;
  664. DSpContextReference        theContext;
  665. OSStatus                theError;
  666. DSpAltBufferReference    theUnderlay;
  667. UInt32                    theDisplayWidth, theDisplayHeight;
  668. CGrafPtr                theAltBufferPort;
  669. GDHandle                theAltBufferGDevice, theOldGDevice;
  670. GrafPtr                    theOldPort;
  671.     
  672.     printf("\n\n");
  673.     printf("############################################################\n");
  674.     printf("###                  Testing Buffering                   ###\n");
  675.     printf("############################################################\n");
  676.     printf("\n\n");
  677.  
  678.  
  679.     /* find the context */
  680.     MyInitAttributes(&theDesiredAttributes);
  681.  
  682.     theDesiredAttributes.displayWidth            = kDisplayWidth;
  683.     theDesiredAttributes.displayHeight            = kDisplayHeight;
  684.     theDesiredAttributes.colorNeeds                = kDSpColorNeeds_Require;
  685.     theDesiredAttributes.backBufferDepthMask    = kDSpDepthMask_8;
  686.     theDesiredAttributes.displayDepthMask        = kDSpDepthMask_8;
  687.     theDesiredAttributes.backBufferBestDepth    = kDisplayDepth;
  688.     theDesiredAttributes.displayBestDepth        = kDisplayDepth;
  689.     theDesiredAttributes.pageCount                = 2;
  690.  
  691.     if (inUseSingleBuffer)
  692.         theDesiredAttributes.pageCount            = 1;
  693.  
  694.     theError = DSpFindBestContext(&theDesiredAttributes, &theContext);
  695.  
  696.     if (theError && kDSpContextNotFoundErr != theError)
  697.     {
  698.         ErrorMessage("DSpFindBestContext", theError);
  699.         return;
  700.     }
  701.  
  702.     if (kDSpContextNotFoundErr == theError)
  703.     {
  704.         printf("# Unable to find a matching context for the following attributes:\n");
  705.         DumpContextAttributes(&theDesiredAttributes);
  706.         return;
  707.     }
  708.  
  709.     theDisplayWidth = kDisplayWidth;
  710.     theDisplayHeight = kDisplayHeight;
  711.     
  712.     /*
  713.     ** Here is where I need to OR in the value to use page flipping.  If
  714.     ** I had used the value when calling DSpFindBestContext() then it would
  715.     ** have only considered displays that have page flipping hardware, but
  716.     ** I want to run with software buffering too.
  717.     */
  718.     theDesiredAttributes.contextOptions |= kDSpContextOption_PageFlip;
  719.  
  720.     /*
  721.     ** If page flipping isn't available, then software buffering will
  722.     ** be used.  DS can use double or triple buffering depending on the
  723.     ** state of the kDSpContextOption_TripleBuffer option bit.
  724.     **
  725.     ** If you only want double buffering, perhaps because of memory
  726.     ** constraints then you should turn off the option bit.
  727.     **
  728.     ** If you leave the bit on and there is hardware page flipping
  729.     ** available (and you haven't turned off that option bit), but
  730.     ** there are only 2 video pages (not three) then DS will consider
  731.     ** page flipping to be more important of an option than triple
  732.     ** buffering and will drop you down to 2 VRAM pages (leaving you
  733.     ** still page flipping).
  734.     **
  735.     */
  736.  
  737.     //•    theDesiredAttributes.contextOptions &= ~kDSpContextOption_TripleBuffer;
  738.  
  739.     //•    set vbl sync
  740.     if (false == gVBLSync)
  741.         theDesiredAttributes.contextOptions |= kDSpContextOption_DontSyncVBL;
  742.             
  743.     //• reset page count
  744.     theDesiredAttributes.pageCount                = 2;
  745.     if (inUseSingleBuffer)
  746.         theDesiredAttributes.pageCount            = 1;
  747.         
  748.     /* reserve the context */    
  749.     theError = DSpContext_Reserve(theContext, &theDesiredAttributes);
  750.  
  751.     if (theError)
  752.     {
  753.         ErrorMessage("DSpContext_Reserve", theError);
  754.         return;
  755.     }
  756.         
  757.     /*
  758.     ** If you are in a debug cycle, you may want to enable debugging mode
  759.     ** in DrawSprocket so that a fade out, followed by a break in the
  760.     ** debugger, won't leave you with nothing to see.
  761.     **
  762.     ** You can also create a folder in same folder as your game, and name
  763.     ** it "DSpSetDebugMode", this will also cause DSp to enter debug mode.
  764.     ** This method is handy if you don't want to rebuild your game with
  765.     ** the call just to debug it.
  766.     */
  767.  
  768.     //•    DSpSetDebugMode(true);
  769.     
  770.     /*
  771.     ** fade out all displays to black, you must have at least one reserved
  772.     ** context to do this or you will get an error.  A game should always
  773.     ** fade to black before activating a context because if the activation
  774.     ** causes a resolution change the user will see a very ugly twitch in
  775.     ** the display.
  776.     */
  777.  
  778.     theError = DSpContext_FadeGammaOut(nil, nil);
  779.  
  780.     if (theError)
  781.     {
  782.         ErrorMessage("DSpContext_FadeGammaOut", theError);
  783.         DSpContext_FadeGammaIn(nil, nil);
  784.         DSpContext_Release(theContext);
  785.  
  786.         return;
  787.     }
  788.     
  789.     /* put the context into the active state */
  790.     theError = DSpContext_SetState(theContext, kDSpContextState_Active);
  791.  
  792.     if (theError)
  793.     {
  794.         ErrorMessage("DSpContext_SetState", theError);
  795.         DSpContext_FadeGammaIn(nil, nil);
  796.         DSpContext_Release(theContext);
  797.  
  798.         return;
  799.     }
  800.  
  801.     /* fade back in */
  802.     theError = DSpContext_FadeGammaIn(nil, nil);
  803.  
  804.     if (theError)
  805.     {
  806.         ErrorMessage("DSpContext_FadeGammaIn", theError);
  807.         DSpContext_Release(theContext);
  808.  
  809.         return;
  810.     }
  811.     
  812.     /*
  813.     ** allocate an alt buffer that will be used for the underlay.  An
  814.     ** underlay is useful in games that have a need to restore from a
  815.     ** static background.
  816.     */
  817.  
  818.     theError = DSpAltBuffer_New(theContext, false, 0, &theUnderlay);
  819.  
  820.     if (theError)
  821.     {
  822.         DSpContext_Release(theContext);
  823.         ErrorMessage("DSpAltBuffer_New (underlay)", theError);
  824.  
  825.         return;
  826.     }
  827.     
  828.     theError = DSpContext_SetUnderlayAltBuffer(theContext, theUnderlay);
  829.  
  830.     if (theError)
  831.     {
  832.         DSpContext_Release(theContext);
  833.         ErrorMessage("DSpContext_SetUnderlayAltBuffer", theError);
  834.  
  835.         return;
  836.     }
  837.  
  838.     //•    do the double buffering
  839.     {    
  840.     UInt32    theColorIndex, theXPos, theYPos;
  841.     Rect    theRect;
  842.         
  843.         GetPort(&theOldPort);
  844.         theOldGDevice = GetGDevice();
  845.         
  846.         /* set the alt buffer to be the current port */
  847.         theError = DSpAltBuffer_GetCGrafPtr(theUnderlay, kDSpBufferKind_Normal, &theAltBufferPort, &theAltBufferGDevice);
  848.  
  849.         if (theError)
  850.         {
  851.             ErrorMessage("DSpAltBuffer_GetCGrafPtr (underlay)", theError);
  852.             DSpContext_FadeGammaIn(nil, nil);
  853.             DSpContext_Release(theContext);
  854.  
  855.             return;
  856.         }
  857.         
  858.         /*
  859.         ** if you want to use QuickDraw or any other toolbox rendering
  860.         ** code, you must setup the GDevice as well as the port when
  861.         ** working with AltBuffers!
  862.         */
  863.  
  864.         SetPort((GrafPtr)theAltBufferPort);
  865.         SetGDevice(theAltBufferGDevice);
  866.  
  867.         /*
  868.         ** fill the underlay buffer with a pattern or clear it
  869.         */
  870.  
  871.         if (inUseUnderlay)
  872.         {
  873.             /*
  874.             ** draw a pattern into the underlay buffer. this pattern will be
  875.             ** restored every time I get the back buffer
  876.             */
  877.             theColorIndex = 0;
  878.  
  879.             for (theYPos = 0; theYPos < theDesiredAttributes.displayHeight; theYPos += kRectSize)
  880.             {
  881.                 for(theXPos = 0; theXPos < theDesiredAttributes.displayWidth; theXPos += kRectSize)
  882.                 {
  883.                     SetRect(&theRect, 0, 0, kRectSize, kRectSize);
  884.                     OffsetRect(&theRect, theXPos, theYPos);
  885.                     theAltBufferPort->fgColor = theColorIndex % 255;
  886.                     
  887.                     PaintRect(&theRect);
  888.  
  889.                     theColorIndex++;            
  890.                 }
  891.             }
  892.         }
  893.         else
  894.         {
  895.             ForeColor(blackColor);
  896.             BackColor(whiteColor);
  897.             SetRect(&theRect, 0, 0, theDesiredAttributes.displayWidth, theDesiredAttributes.displayHeight);
  898.             EraseRect(&theRect);
  899.         }
  900.             
  901.         SetPort(theOldPort);
  902.         SetGDevice(theOldGDevice);
  903.     }
  904.         
  905.     /*
  906.     ** this test slides a black vertical bar left and right on the
  907.     ** display, producing an image where any tearing is amplified.
  908.     */
  909.  
  910.     {
  911.     RGBColor    theColor, theTextColor;
  912.     Rect        theRectangleRect, theRect;
  913.     UInt32        theStartTick, theMaxTick, theCurrentTick;
  914.     UInt32        theCount, theRectangleDelta;
  915.     UInt32        theWidth, theXPos, theYPos;
  916.     CGrafPtr    theBackBuffer;
  917.     UInt32        theXSquares, theYSquares;
  918.     
  919.     theXSquares = theDesiredAttributes.displayWidth / kRectSize;
  920.     theYSquares = theDesiredAttributes.displayHeight / kRectSize;
  921.     
  922.     theColor.red = 0;
  923.     theColor.green = 0;
  924.     theColor.blue = 0;
  925.     theTextColor.red = 0xFFFF;
  926.     theTextColor.green = 0xFFFF;
  927.     theTextColor.blue = 0xFFFF;
  928.  
  929.     /* rectangle will be 1/8 the display width, and all of the height */
  930.     SetRect(&theRectangleRect, 0, 0, theDesiredAttributes.displayWidth >> 3,
  931.         theDesiredAttributes.displayHeight);
  932.     
  933.     theStartTick = theCurrentTick = TickCount();
  934.     theMaxTick = theStartTick + (15 * 60);
  935.     theCount = 0;
  936.     theRectangleDelta = 3;
  937.  
  938.     while (theCurrentTick < theMaxTick)
  939.     {
  940.         /*
  941.         ** every so often change the color of one of the squares
  942.         ** in the underlay
  943.         */
  944.  
  945.         if ((theCurrentTick % 10) == 0)
  946.         {
  947.         RGBColor    theNewColor;
  948.         UInt32        theX, theY;
  949.         Rect        theRect;
  950.             
  951.             SetPort((GrafPtr)theAltBufferPort);
  952.             SetGDevice(theAltBufferGDevice);
  953.             
  954.             theNewColor.red = Random();
  955.             theNewColor.green = Random();
  956.             theNewColor.blue = Random();
  957.             
  958.             theX = Random() % theXSquares;
  959.             theY = Random() % theYSquares;
  960.             
  961.             theRect.left = theX * kRectSize;
  962.             theRect.right = theRect.left + kRectSize;
  963.             theRect.top = theY * kRectSize;
  964.             theRect.bottom = theRect.top + kRectSize;
  965.             
  966.             RGBForeColor(&theNewColor);
  967.             PaintRect(&theRect);
  968.             DSpAltBuffer_InvalRect(theUnderlay, &theRect);
  969.         }
  970.         
  971.         /* get the back buffer */
  972.         theError = DSpContext_GetBackBuffer(theContext, kDSpBufferKind_Normal, &theBackBuffer);
  973.  
  974.         if (theError)
  975.         {
  976.             ErrorMessage("DSpContext_GetBackBuffer", theError);
  977.             DSpContext_Release(theContext);
  978.  
  979.             return;
  980.         }
  981.         
  982.         /* set the back buffer to be the current port */
  983.         SetPort((GrafPtr)theBackBuffer);
  984.         
  985.         /* fill the display with a sliding vertical rectangle */
  986.         RGBForeColor(&theColor);        
  987.         PaintRect(&theRectangleRect);
  988.  
  989.         /* inval the new rect position */        
  990.         theError = DSpContext_InvalBackBufferRect(theContext, &theRectangleRect);
  991.             
  992.         if ((theRectangleRect.right + theRectangleDelta) > theDesiredAttributes.displayWidth)
  993.             theRectangleDelta = -theRectangleDelta;
  994.         
  995.         if ((theRectangleRect.left + theRectangleDelta) < 0)
  996.             theRectangleDelta = -theRectangleDelta;
  997.  
  998.         theRectangleRect.left += theRectangleDelta;
  999.         theRectangleRect.right += theRectangleDelta;
  1000.  
  1001.         // draw a frame counter
  1002.         sprintf((char *)&gTextBuffer[1],
  1003.             "This is frame %d (%d ticks remaining, %.1f fps)",
  1004.             theCount + 1, theMaxTick - theCurrentTick,
  1005.             (float)(theCount / ((theCurrentTick - theStartTick) / 60.0)));
  1006.  
  1007.         gTextBuffer[0] = strlen((char *)&gTextBuffer[1]);
  1008.         theWidth = StringWidth((ConstStr255Param)gTextBuffer);
  1009.         theXPos = (theDisplayWidth >> 1) - (theWidth >> 1);
  1010.         theYPos = theDisplayHeight - 20;
  1011.  
  1012.         theTextColor.red = 0;
  1013.         theTextColor.green = 0;
  1014.         theTextColor.blue = 0;
  1015.         RGBForeColor(&theTextColor);
  1016.         SetRect(&theRect, theXPos - 10, theYPos - 20, theXPos + theWidth + 10, theYPos + 10);
  1017.         PaintRect(&theRect);
  1018.         
  1019.         theError = DSpContext_InvalBackBufferRect(theContext, &theRect);
  1020.  
  1021.         theTextColor.red = 0;
  1022.         theTextColor.green = 0xFFFF;
  1023.         theTextColor.blue = 0xFFFF;
  1024.         RGBForeColor(&theTextColor);
  1025.         FrameRect(&theRect);
  1026.         
  1027.         MoveTo(theXPos, theYPos);
  1028.         DrawString((ConstStr255Param)gTextBuffer);
  1029.         
  1030.         // swap the buffers
  1031.         theError = DSpContext_SwapBuffers(theContext, nil, 0);
  1032.  
  1033.         if (theError)
  1034.         {
  1035.             ErrorMessage("DSpContext_SwapBuffers", theError);
  1036.             DSpContext_Release(theContext);
  1037.             return;
  1038.         }
  1039.         
  1040.         /* increase frame counter */
  1041.         theCount++;
  1042.         theCurrentTick = TickCount();
  1043.     }
  1044.  
  1045.     }
  1046.     
  1047.     /*
  1048.     ****************************************************************************
  1049.     ** cleanup
  1050.     ****************************************************************************
  1051.     */    
  1052.  
  1053.     if (inUseUnderlay)
  1054.     {
  1055.         SetPort(theOldPort);
  1056.         SetGDevice(theOldGDevice);
  1057.     }
  1058.     
  1059.     /* fade to black */
  1060.     theError = DSpContext_FadeGammaOut(nil, nil);
  1061.  
  1062.     if (theError)
  1063.     {
  1064.         ErrorMessage("DSpContext_FadeGammaIn", theError);
  1065.         DSpContext_Release(theContext);
  1066.         return;
  1067.     }
  1068.  
  1069.     /* remove the underlay & release it */
  1070.     DSpContext_SetUnderlayAltBuffer(theContext, nil);
  1071.     DSpAltBuffer_Dispose(theUnderlay);
  1072.     theUnderlay = nil;
  1073.     
  1074.     /* put the context into the inactive state */
  1075.     theError = DSpContext_SetState(theContext, kDSpContextState_Inactive);
  1076.  
  1077.     if (theError)
  1078.     {
  1079.         ErrorMessage("DSpContext_SetState", theError);
  1080.         DSpContext_FadeGammaIn(nil, nil);
  1081.         DSpContext_Release(theContext);
  1082.  
  1083.         return;
  1084.     }
  1085.  
  1086.     /* fade back in */
  1087.     theError = DSpContext_FadeGammaIn(nil, nil);
  1088.  
  1089.     if (theError)
  1090.     {
  1091.         ErrorMessage("DSpContext_FadeGammaIn", theError);
  1092.         DSpContext_Release(theContext);
  1093.  
  1094.         return;
  1095.     }
  1096.     
  1097.     /* release the context */
  1098.     theError = DSpContext_Release(theContext);
  1099.  
  1100.     if (theError)
  1101.     {
  1102.         ErrorMessage("DSpContext_Release", theError);
  1103.         return;
  1104.     }
  1105. }
  1106.  
  1107. //•    --------------------    TextContextCLUT
  1108.  
  1109. void
  1110. TestContextCLUT(void)
  1111. {
  1112. DSpContextAttributes    theDesiredAttributes;
  1113. DSpContextReference        theContext;
  1114. OSStatus                theError;
  1115. RGBColor                theBlankingColor;
  1116.     
  1117.     printf("\n\n");
  1118.     printf("############################################################\n");
  1119.     printf("###                     Testing CLUT                     ###\n");
  1120.     printf("############################################################\n");
  1121.     printf("\n\n");
  1122.  
  1123.  
  1124.     /* find the context */
  1125.     MyInitAttributes(&theDesiredAttributes);
  1126.  
  1127.     theDesiredAttributes.displayWidth            = kDisplayWidth;
  1128.     theDesiredAttributes.displayHeight            = kDisplayHeight;
  1129.     theDesiredAttributes.colorNeeds                = kDSpColorNeeds_Require;
  1130.     theDesiredAttributes.backBufferDepthMask    = kDSpDepthMask_8;
  1131.     theDesiredAttributes.displayDepthMask        = kDSpDepthMask_8;
  1132.     theDesiredAttributes.backBufferBestDepth    = kDisplayDepth;
  1133.     theDesiredAttributes.displayBestDepth        = kDisplayDepth;
  1134.     theDesiredAttributes.pageCount                = 2;
  1135.  
  1136.     theError = DSpFindBestContext(&theDesiredAttributes, &theContext);
  1137.  
  1138.     if (theError && kDSpContextNotFoundErr != theError)
  1139.     {
  1140.         ErrorMessage("DSpFindBestContext", theError);
  1141.         return;
  1142.     }
  1143.  
  1144.     if (kDSpContextNotFoundErr == theError)
  1145.     {
  1146.         printf("# Unable to find a matching context for the following attributes:\n");
  1147.         DumpContextAttributes(&theDesiredAttributes);
  1148.  
  1149.         return;
  1150.     }
  1151.  
  1152.     /* reserve the context */    
  1153.     theError = DSpContext_Reserve(theContext, &theDesiredAttributes);
  1154.  
  1155.     if (theError)
  1156.     {
  1157.         ErrorMessage("DSpContext_Reserve", theError);
  1158.         return;
  1159.     }
  1160.  
  1161.     /* set the blanking color to white, just for the heck of it */
  1162.     theBlankingColor.red = 0xFFFFF;    
  1163.     theBlankingColor.green = 0xFFFFF;    
  1164.     theBlankingColor.blue = 0xFFFFF;    
  1165.  
  1166.     theError = DSpSetBlankingColor(&theBlankingColor);
  1167.  
  1168.     if (theError)
  1169.     {
  1170.         ErrorMessage("DSpSetBlankingColor", theError);
  1171.         return;
  1172.     }
  1173.  
  1174.     /* fade out all displays to black */
  1175.     theError = DSpContext_FadeGammaOut(nil, nil);
  1176.  
  1177.     if (theError)
  1178.     {
  1179.         ErrorMessage("DSpContext_FadeGammaOut", theError);
  1180.         DSpContext_FadeGammaIn(nil, nil);
  1181.         DSpContext_Release(theContext);
  1182.  
  1183.         return;
  1184.     }
  1185.     
  1186.     /* put the context into the active state */
  1187.     theError = DSpContext_SetState(theContext, kDSpContextState_Active);
  1188.  
  1189.     if (theError)
  1190.     {
  1191.         ErrorMessage("DSpContext_SetState", theError);
  1192.         DSpContext_FadeGammaIn(nil, nil);
  1193.         DSpContext_Release(theContext);
  1194.  
  1195.         return;
  1196.     }
  1197.  
  1198.     /* fade back in */
  1199.     theError = DSpContext_FadeGammaIn(nil, nil);
  1200.  
  1201.     if (theError)
  1202.     {
  1203.         ErrorMessage("DSpContext_FadeGammaIn", theError);
  1204.         DSpContext_Release(theContext);
  1205.  
  1206.         return;
  1207.     }
  1208.     
  1209.     /*
  1210.     ****************************************************************************
  1211.     ** do the CLUT testing
  1212.     ****************************************************************************
  1213.     */
  1214.     
  1215.     /* draw a pattern into the back buffer and cycle it */
  1216.     {
  1217.     UInt32        thePosition, theColorIndex, theXPos, theYPos;
  1218.     CGrafPtr    theBackBuffer;
  1219.     ColorSpec    theOriginalColors[256];
  1220.     
  1221.     /* get the back buffer */
  1222.     theError = DSpContext_GetBackBuffer(theContext, kDSpBufferKind_Normal, &theBackBuffer);
  1223.  
  1224.     if (theError)
  1225.     {
  1226.         ErrorMessage("DSpContext_GetBackBuffer", theError);
  1227.         DSpContext_Release(theContext);
  1228.  
  1229.         return;
  1230.     }
  1231.     
  1232.     /* set the back buffer to be the current port */
  1233.     SetPort((GrafPtr)theBackBuffer);
  1234.  
  1235.     /* draw a pattern into the back buffer */
  1236.     theColorIndex = 0;
  1237.  
  1238.     for(theYPos = 0; theYPos < theDesiredAttributes.displayHeight; theYPos += kRectSize)
  1239.     {
  1240.         for(theXPos = 0; theXPos < theDesiredAttributes.displayWidth; theXPos += kRectSize)
  1241.         {
  1242.         Rect    theRect;
  1243.             
  1244.             SetRect(&theRect, 0, 0, kRectSize, kRectSize);
  1245.             OffsetRect(&theRect, theXPos, theYPos);
  1246.             theBackBuffer->fgColor = theColorIndex % 255;
  1247.             
  1248.             PaintRect(&theRect);
  1249.  
  1250.             theColorIndex++;            
  1251.         }
  1252.     }
  1253.     
  1254.     /* bring the back buffer to the front */
  1255.     theError = DSpContext_SwapBuffers(theContext, nil, 0);
  1256.  
  1257.     if (theError)
  1258.     {
  1259.         ErrorMessage("DSpContext_SwapBuffers", theError);
  1260.         DSpContext_Release(theContext);
  1261.  
  1262.         return;
  1263.     }
  1264.     
  1265.     /*
  1266.     ** get the original color table
  1267.     **
  1268.     ** unfortunately, these probably aren't the real colors, since
  1269.     ** the way that gamma works on the Mac is to remap the indexed
  1270.     ** color table to new colors.  In other words, these colors are
  1271.     ** gamma corrected versions of the ones that were originally set.
  1272.     **
  1273.     */
  1274.  
  1275.     theError = DSpContext_GetCLUTEntries(theContext, theOriginalColors,    0, 255);
  1276.  
  1277.     if (theError)
  1278.     {
  1279.         ErrorMessage("DSpContext_GetCLUTEntries", theError);
  1280.         DSpContext_Release(theContext);
  1281.  
  1282.         return;
  1283.     }
  1284.     
  1285.     /* cycle the colors */
  1286.     while (! Button())
  1287.     {
  1288.     ColorSpec    theSpec[256], theTempSpec;
  1289.         
  1290.         /* rotate them */
  1291.         theTempSpec = theOriginalColors[0];
  1292.         
  1293.         for(theColorIndex = 0; theColorIndex < 255; theColorIndex++)
  1294.             theSpec[theColorIndex].rgb = theOriginalColors[(theColorIndex + thePosition) % 255].rgb;
  1295.  
  1296.         theSpec[255].rgb = theTempSpec.rgb;
  1297.         
  1298.         thePosition++;
  1299.  
  1300.         if (thePosition > 255)
  1301.             thePosition = 0;
  1302.         
  1303.         /* set the entries */
  1304.         theError = DSpContext_SetCLUTEntries(theContext, theSpec, 0, 255);
  1305.  
  1306.         if (theError)
  1307.         {
  1308.             ErrorMessage("DSpContext_SetCLUTEntries", theError);
  1309.             DSpContext_Release(theContext);
  1310.  
  1311.             return;
  1312.         }
  1313.     }
  1314.  
  1315.     }
  1316.     
  1317.     /*
  1318.     ****************************************************************************
  1319.     ** cleanup
  1320.     ****************************************************************************
  1321.     */    
  1322.  
  1323.     /* fade to black */
  1324.     theError = DSpContext_FadeGammaOut(nil, nil);
  1325.  
  1326.     if (theError)
  1327.     {
  1328.         ErrorMessage("DSpContext_FadeGammaIn", theError);
  1329.         DSpContext_Release(theContext);
  1330.  
  1331.         return;
  1332.     }
  1333.  
  1334.     /* put the context into the inactive state */
  1335.     theError = DSpContext_SetState(theContext, kDSpContextState_Inactive);
  1336.  
  1337.     if (theError)
  1338.     {
  1339.         ErrorMessage("DSpContext_SetState", theError);
  1340.         DSpContext_FadeGammaIn(nil, nil);
  1341.         DSpContext_Release(theContext);
  1342.  
  1343.         return;
  1344.     }
  1345.  
  1346.     /* fade back in */
  1347.     theError = DSpContext_FadeGammaIn(nil, nil);
  1348.  
  1349.     if (theError)
  1350.     {
  1351.         ErrorMessage("DSpContext_FadeGammaIn", theError);
  1352.         DSpContext_Release(theContext);
  1353.  
  1354.         return;
  1355.     }
  1356.     
  1357.     /* release the context */
  1358.     theError = DSpContext_Release(theContext);
  1359.  
  1360.     if (theError)
  1361.     {
  1362.         ErrorMessage("DSpContext_Release", theError);
  1363.         return;
  1364.     }
  1365. }
  1366.  
  1367. //•    --------------------    TestUserSelectContext
  1368.  
  1369. void
  1370. TestUserSelectContext(void)
  1371. {
  1372. DSpContextAttributes    theDesiredAttributes;
  1373. DSpContextAttributes    theActualAttributes;
  1374. DSpContextReference        theContext;
  1375. OSStatus                theError;
  1376. Boolean                    theShowDialogFlag;
  1377. DisplayIDType            theDisplayID;
  1378.     
  1379.     printf("\n\n");
  1380.     printf("############################################################\n");
  1381.     printf("###                     Testing CLUT                     ###\n");
  1382.     printf("############################################################\n");
  1383.     printf("\n\n");
  1384.  
  1385.     /* find the context */
  1386.     MyInitAttributes(&theDesiredAttributes);
  1387.  
  1388.     theDesiredAttributes.displayWidth            = kDisplayWidth;
  1389.     theDesiredAttributes.displayHeight            = kDisplayHeight;
  1390.     theDesiredAttributes.colorNeeds                = kDSpColorNeeds_Require;
  1391.     theDesiredAttributes.backBufferDepthMask    = kDSpDepthMask_8;
  1392.     theDesiredAttributes.displayDepthMask        = kDSpDepthMask_8;
  1393.     theDesiredAttributes.backBufferBestDepth    = kDisplayDepth;
  1394.     theDesiredAttributes.displayBestDepth        = kDisplayDepth;
  1395.     theDesiredAttributes.pageCount                = 2;
  1396.  
  1397.     /*
  1398.     ** see if there are enough choices available for the user to
  1399.     ** choose from, this can be used if I needed to determine
  1400.     ** whether or not to enable a menu item, etc.
  1401.     */
  1402.     theError = DSpCanUserSelectContext(&theDesiredAttributes, &theShowDialogFlag);
  1403.  
  1404.     if (theError)
  1405.     {
  1406.         ErrorMessage("DSpCanUserSelectContext", theError);
  1407.         return;
  1408.     }
  1409.  
  1410.     if (false == theShowDialogFlag)
  1411.     {
  1412.         printf("There are not enough choices to warrant asking the user.\n");
  1413.         return;
  1414.     }
  1415.     
  1416.     /*
  1417.     ** put up the choice dialog, I don't care about what display it
  1418.     ** appears on, nor do I care to know about update events
  1419.     */
  1420.     theError = DSpUserSelectContext(&theDesiredAttributes, 0, nil, &theContext);
  1421.  
  1422.     if (theError)
  1423.     {
  1424.         /*
  1425.         ** since we know that there were possible matches available (because
  1426.         ** we called DSpCanUserSelectContext), we know that a context-not-found
  1427.         ** error means that the user canceled the dialog
  1428.         */
  1429.         if (kDSpContextNotFoundErr == theError)
  1430.             printf("The user canceled the dialog.\n");
  1431.         else
  1432.             ErrorMessage("DSpUserSelectContext", theError);
  1433.  
  1434.         return;
  1435.     }
  1436.  
  1437.     /* tell the user about the results */
  1438.     printf("User-Selected Context for the following attributes...\n");
  1439.     DumpContextAttributes(&theDesiredAttributes);
  1440.     
  1441.     theError = DSpContext_GetDisplayID(theContext, &theDisplayID);
  1442.  
  1443.     if (theError)
  1444.     {
  1445.         ErrorMessage("DSpContext_GetDisplayID", theError);
  1446.         return;
  1447.     }
  1448.  
  1449.     theError = DSpContext_GetAttributes(theContext, &theActualAttributes);
  1450.  
  1451.     if (theError)
  1452.     {
  1453.         ErrorMessage("DSpContext_GetAttributes", theError);
  1454.         return;
  1455.     }
  1456.  
  1457.     printf("...is the context on display id %d with these attributes:\n", theDisplayID);
  1458.     DumpContextAttributes(&theActualAttributes);
  1459. }
  1460.  
  1461. //•    --------------------    TestFlatContexts
  1462.  
  1463. void
  1464. TestFlatContexts(void)
  1465. {
  1466. DSpContextAttributes    theDesiredAttributes;
  1467. DSpContextReference        theContext, theRestoredContext;
  1468. OSStatus                theError;
  1469. UInt32                    theFlatContextSize;
  1470. Ptr                        theFlatContextBuffer = nil;
  1471.     
  1472.     printf("\n\n");
  1473.     printf("############################################################\n");
  1474.     printf("###                 Testing Flat Contexts                ###\n");
  1475.     printf("############################################################\n");
  1476.     printf("\n\n");
  1477.  
  1478.  
  1479.     /* find the context */
  1480.     MyInitAttributes(&theDesiredAttributes);
  1481.  
  1482.     theDesiredAttributes.displayWidth            = kDisplayWidth;
  1483.     theDesiredAttributes.displayHeight            = kDisplayHeight;
  1484.     theDesiredAttributes.colorNeeds                = kDSpColorNeeds_Require;
  1485.     theDesiredAttributes.backBufferDepthMask    = kDSpDepthMask_8;
  1486.     theDesiredAttributes.displayDepthMask        = kDSpDepthMask_8;
  1487.     theDesiredAttributes.backBufferBestDepth    = kDisplayDepth;
  1488.     theDesiredAttributes.displayBestDepth        = kDisplayDepth;
  1489.     theDesiredAttributes.pageCount                = 2;
  1490.  
  1491.     theError = DSpFindBestContext(&theDesiredAttributes, &theContext);
  1492.  
  1493.     if (theError && kDSpContextNotFoundErr != theError)
  1494.     {
  1495.         ErrorMessage("DSpFindBestContext", theError);
  1496.         return;
  1497.     }
  1498.  
  1499.     if (kDSpContextNotFoundErr == theError)
  1500.     {
  1501.         printf("# Unable to find a matching context for the following attributes:\n");
  1502.         DumpContextAttributes(&theDesiredAttributes);
  1503.  
  1504.         return;
  1505.     }
  1506.     
  1507.     /* get the flattened size & allocate space for it */
  1508.     theError = DSpContext_GetFlattenedSize(theContext, &theFlatContextSize);
  1509.  
  1510.     if (theError)
  1511.     {
  1512.         ErrorMessage("DSpContext_GetFlattenedSize", theError);
  1513.         return;
  1514.     }
  1515.  
  1516.     theFlatContextBuffer = NewPtr(theFlatContextSize);
  1517.  
  1518.     if (nil == theFlatContextBuffer)
  1519.     {
  1520.         ErrorMessage("not enough memory to allocate flat context", 0);
  1521.         return;
  1522.     }
  1523.     
  1524.     /* flatten the context */
  1525.     theError = DSpContext_Flatten(theContext, theFlatContextBuffer);
  1526.  
  1527.     if (theError)
  1528.         ErrorMessage("DSpContext_Flatten", theError);
  1529.     
  1530.     /* restore the context from the flattened version */
  1531.     if (noErr == theError)
  1532.     {
  1533.         theError = DSpContext_Restore(theFlatContextBuffer, &theRestoredContext);
  1534.  
  1535.         if (theError)
  1536.             ErrorMessage("DSpContext_Flatten", theError);
  1537.  
  1538.         /* same context? */
  1539.         if (theRestoredContext == theContext)
  1540.             printf("restored context successfully\n");
  1541.         else
  1542.             printf("Error: restored context didn't match!\n");
  1543.         
  1544.     }
  1545.     
  1546.     /* cleanup */
  1547.     DisposePtr(theFlatContextBuffer);
  1548. }
  1549.  
  1550. //•    --------------------    TestGetVersion
  1551.  
  1552. static void
  1553. TestGetVersion(void)
  1554. {
  1555. NumVersion    theVersion;
  1556. char        buffer[128];
  1557.  
  1558.     printf("\n\n");
  1559.     printf("############################################################\n");
  1560.     printf("###                 Testing DSpGetVersion                ###\n");
  1561.     printf("############################################################\n");
  1562.     printf("\n\n");
  1563.  
  1564.     if ((Ptr) kUnresolvedCFragSymbolAddress == (Ptr) DSpGetVersion)
  1565.     {
  1566.         printf("Error: DSpGetVersion not present.  Your DrawSprocket is too old.");
  1567.         return;
  1568.     }
  1569.     
  1570.     theVersion = DSpGetVersion();
  1571.  
  1572.     sprintf(buffer, "DrawSprocket v%d.%d.%d",
  1573.         theVersion.majorRev,
  1574.         theVersion.minorAndBugRev >> 4,
  1575.         theVersion.minorAndBugRev & 0x0F);
  1576.  
  1577.     switch (theVersion.stage)
  1578.     {
  1579.         case 0x20:
  1580.             sprintf(buffer, "%s development %d\n\n", buffer, theVersion.nonRelRev);
  1581.             break;
  1582.             
  1583.         case 0x40:
  1584.             sprintf(buffer, "%s alpha %d\n\n", buffer, theVersion.nonRelRev);
  1585.             break;
  1586.             
  1587.         case 0x60:
  1588.             sprintf(buffer, "%s beta %d\n\n", buffer, theVersion.nonRelRev);
  1589.             break;
  1590.             
  1591.         case 0x80:
  1592.             sprintf(buffer, "%s final %d\n\n", buffer, theVersion.nonRelRev);
  1593.             break;
  1594.             
  1595.     }
  1596.  
  1597.     printf(buffer);
  1598. }
  1599.